import React, { useRef, useState, useEffect, useImperativeHandle, forwardRef } from 'react';
import { Tag, Space, Input, Tooltip } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
import type { InputRef } from 'antd';
import uuid from 'uuid-v4';
import { units } from '@library';
import useQueryControlWrap from '../../hooks/useQueryControlWrap';
import { CanvasItemProps } from './../../interface';
import styles from './tag.module.scss';

const isEn = localStorage.i18nextLng === 'en';

const tagInputStyle: React.CSSProperties = {
  width: 64,
  height: 30,
  marginInlineEnd: 8,
  verticalAlign: 'top',
};

const tagPlusStyle: React.CSSProperties = {
  height: 30,
  background: '#FEFEFE',
  borderStyle: 'dashed',
};

type TagItem = Record<string, any>;

type TagRef = {
  setData(tags: TagItem[]): void;
  getData(): TagItem[] | boolean;
  getDataNotCheck(): TagItem[];
}

export interface TagProps extends CanvasItemProps {
  required: boolean;
  title: string;
  titleEn?: string;
  tagProps: {
    showFieldName: string;
  }
}

export default forwardRef((props: TagProps, ref: React.Ref<TagRef>) => {
  const { isDesign, domComplete, tagProps, title, titleEn, name, required, disabled, onValuesChange, ...canvasProps } = props;
  const [tags, setTags] = useState<TagItem[]>([]);
  const [inputVisible, setInputVisible] = useState(false);
  const [inputValue, setInputValue] = useState('');
  const [editInputIndex, setEditInputIndex] = useState(-1);
  const [editInputValue, setEditInputValue] = useState('');
  const inputRef = useRef<InputRef>(null);
  const editInputRef = useRef<InputRef>(null);
  const isSyncData = useRef(false); // 标记是否向上同步数据

  useQueryControlWrap(canvasProps.id, '', domComplete);

  useImperativeHandle(ref, () => ({
    setData: (tags: TagItem[]) => {
      setTags((tags || []).map(item => {
        if(item.id) return item;
        return { ...item, id: uuid(), _isCreate: true }
      }));
      isSyncData.current = false;
    },
    getDataNotCheck: () => {
      const newTags: TagItem[] = JSON.parse(JSON.stringify(tags));
      newTags.forEach(item => {
        if(item._isCreate) {
          delete item.id;
          delete item._isCreate
        }
      });
      return newTags
    },
    getData: () => {
      const empty = tags.filter(item => !item[tagProps.showFieldName]);

      if((empty.length || tags.length === 0) && required) {
        units.message.warning(window.$app.t('tagDataSoureTmptyTip'));
        return false;
      }
      
      const newTags: TagItem[] = JSON.parse(JSON.stringify(tags));
      newTags.forEach(item => {
        if(item._isCreate) {
          delete item.id;
          delete item._isCreate
        }
      }); 

      return newTags
    }
  }));
  console.log(tags);
  useEffect(() => {
    if (inputVisible) {
      inputRef.current?.focus();
    }
  }, [inputVisible]);

  useEffect(() => {
    editInputRef.current?.focus();
  }, [editInputValue]);

  useEffect(() => {
    if (isSyncData.current) {
      onValuesChange?.(name, tags);
      isSyncData.current = false
    }
  }, [tags]);

  const handleClose = (removedTag: string) => {
    isSyncData.current = true;
    const newTags = tags.filter((tag) => tag.id !== removedTag);
    setTags(newTags);
  };

  const showInput = () => {
    setInputVisible(true);
  };

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setInputValue(e.target.value);
  };

  const handleInputConfirm = () => {
    isSyncData.current = true;
    if (inputValue) {
      setTags([...tags, {
        [tagProps.showFieldName]: inputValue,
        _isCreate: true,
        id: uuid()
      }]);
    }
    setInputVisible(false);
    setInputValue('');
  };

  const handleEditInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setEditInputValue(e.target.value);
  };

  const handleEditInputConfirm = () => {
    isSyncData.current = true;
    const newTags = [...tags];
    newTags[editInputIndex][tagProps.showFieldName] = editInputValue;
    setTags(newTags);
    setEditInputIndex(-1);
    setEditInputValue('');
  };

  return (
    <div className={styles.box} id={props._id} {...canvasProps}>
      <div className={styles.hd}>
        {required && <span className={styles.required}>*</span>}
        <span>{isEn ? (titleEn || title) : title}</span>
      </div>
      <Space className={styles.main} size={[0, 8]} wrap>
        {tags.map((tag, index) => {
          if (editInputIndex === index) {
            return (
              <Input
                ref={editInputRef}
                key={tag.id}
                size="small"
                style={tagInputStyle}
                value={editInputValue}
                onChange={handleEditInputChange}
                onBlur={handleEditInputConfirm}
                onPressEnter={handleEditInputConfirm}
              />
            );
          }
          const isLongTag = tag.length > 20;
          const tagElem = (
            <Tag
              closable={!disabled}
              key={tag.id}
              style={{ userSelect: 'none' }}
              onClose={() => handleClose(tag.id)}
            >
              <span
                onDoubleClick={!disabled ? (e) => {
                  setEditInputIndex(index);
                  setEditInputValue(tag[tagProps.showFieldName]);
                  e.preventDefault();
                } : undefined}
              >
                {isLongTag ? `${tag[tagProps.showFieldName]?.slice(0, 20)}...` : tag[tagProps.showFieldName]}
              </span>
            </Tag>
          );
          return isLongTag ? (
            <Tooltip title={tag[tagProps.showFieldName]} key={tag.id}>
              {tagElem}
            </Tooltip>
          ) : (
            tagElem
          );
        })}
        {inputVisible ? (
          <Input
            ref={inputRef}
            type="text"
            size="small"
            style={tagInputStyle}
            value={inputValue}
            onChange={handleInputChange}
            onBlur={handleInputConfirm}
            onPressEnter={handleInputConfirm}
          />
        ) : (
          !disabled && (
            <Tag style={tagPlusStyle} icon={<PlusOutlined />} onClick={showInput}>
              {window.$app.t('add')}
            </Tag>
          )
        )}
      </Space>
    </div>
  );
});